package mapper

import (
	"Infinichat_mixed/entity"
	"Infinichat_mixed/server/s_utils"
	"errors"
	"fmt"
	"github.com/jinzhu/gorm"
)

// 通过ID查询用户
func FindUserByID(id uint) (retUser entity.User) {
	retUser.ID = id
	s_utils.DB.Where("id = ?", id).First(&retUser)
	return retUser
}

// 通过账号查询用户 准确查询
func FindUserByAccount(account string) (retUser entity.User) {
	retUser.Account = account
	s_utils.DB.Where("account = ?", retUser.Account).Find(&retUser)
	return retUser
}

// 通过昵称查询用户 模糊查询
func FindUserByNickName_fuzzy(nickName string) (retUsers []entity.User) {
	s_utils.DB.Where("nickname LIKE ?", "%"+nickName+"%").Find(&retUsers)
	return retUsers
}

// 确认两者是否为好友关系
func IsFriend(sId, tId uint) bool {
	friend := &entity.Friend{}
	friend.Sid = sId
	friend.Tid = tId
	result := s_utils.DB.Where("sid=? AND tid=?", sId, tId).Find(&friend)
	if result.Error != nil {
		// 如果是查询错误 则说明是不存在这条数据 应该是非好友
		return false
	}
	return friend.IsAdd
}

// 好友请求
func AddFriend(sId, tId uint) (err error) {
	Findfriend := &entity.Friend{}
	// 先查询是否有这条数据 没有再创建
	result := s_utils.DB.Where("sid = ? and tid = ?", sId, tId).Find(&Findfriend)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			// 数据不存在
			friend := &entity.Friend{
				Sid: sId,
				Tid: tId,
			}
			result = s_utils.DB.Create(friend)
			if result.Error != nil {
				return result.Error
			}
			return nil
		}
	}
	return nil
}

// 查询好友请求
func FindFriendReq(tId uint) (friends []entity.Friend, err error) {
	result := s_utils.DB.Where("tid=? and is_refused = 0 and is_add = 0", tId).Find(&friends)
	if result.Error != nil {
		return nil, result.Error
	}
	return friends, nil
}

// 同意/拒绝 好友请求
func ProcessAdd(sId, tId uint, flag bool) (err error) {
	friend := &entity.Friend{}
	friend.Sid = sId
	friend.Tid = tId
	friend.IsAdd = flag
	// 若同意 则将friend表中的is_add置为true即可
	if flag {
		result := s_utils.DB.Model(friend).Where("sid=? AND tid=?", sId, tId).Update(&friend)
		if result.Error != nil {
			return result.Error
		}
	} else {
		// 若拒绝 则将 is_refused 置为 true， 等sid读取完 则需要删除
		friend.IsRefused = true
		result := s_utils.DB.Where("sid=? AND tid=?", sId, tId).Update(&friend)
		if result.Error != nil {
			return result.Error
		}
	}

	return nil
}

// 通过账号+密码查询用户
func FindUserByAP(account, password string) (retUser entity.User) {
	retUser.Account = account
	retUser.Password = password
	s_utils.DB.Where("account = ? and password = ?", retUser.Account, retUser.Password).Find(&retUser)
	return retUser
}

// 查看p2p的未读消息
func Unread_p2p(receiver_id uint) (p2p_msg []entity.P2PMsg, err error) {
	result := s_utils.DB.Where("receive_id = ? and is_read = false", receiver_id).Find(&p2p_msg)
	if result.Error != nil {
		err = result.Error
		return p2p_msg, err
	}

	result = s_utils.DB.Model(&p2p_msg).Where("receive_id = ? and is_read = false", receiver_id).Updates("is_read", true)
	if result.Error != nil {
		err = result.Error
		return p2p_msg, err
	}
	return p2p_msg, nil
}

// 查看p2g的未读消息
func Unread_p2m(receiver_id uint) (p2m_msg []entity.P2MMsg, err error) {
	result := s_utils.DB.Where("? not in read_ids", receiver_id).Find(&p2m_msg)
	if result.Error != nil {
		err = result.Error
		return p2m_msg, err
	}

	for _, v := range p2m_msg {
		// 取出所有的 把receiver_id移除
		ids := v.ReadIds
		var filteredIds []uint
		for _, id := range ids {
			if id != receiver_id {
				filteredIds = append(filteredIds, id)
			}
		}
		v.ReadIds = filteredIds
		s_utils.DB.Model(&v).Update(v.ReadIds)
	}

	return p2m_msg, nil
}

// 查看添加好友请求
func FriendAddRequest(target_id uint) (ids []uint, err error) {
	friends := &[]entity.Friend{}
	result := s_utils.DB.Where("tid = ? and is_add = 0 and is_refused = 0", target_id).Find(&friends)
	if result.Error != nil {
		err = result.Error
		return ids, err
	}
	for _, friend := range *friends {
		ids = append(ids, friend.Sid)
	}
	return ids, nil
}

// 查找好友列表
func FindFriendByFid(fid uint) (users []entity.User, err error) {
	tmp := []entity.User{}
	result := s_utils.DB.Table("friend").Select("user.id, user.nickname").
		Joins("left join user on user.id = friend.tid").
		Where("friend.sid = ?", fid).
		Scan(&tmp)

	users = append(users, tmp...)

	tmp = []entity.User{}
	result = s_utils.DB.Table("friend").Select("user.id, user.nickname").
		Joins("left join user on user.id = friend.sid").
		Where("friend.tid = ?", fid).
		Scan(&tmp)

	users = append(users, tmp...)

	if result.Error != nil {
		return nil, result.Error
	}

	return users, nil
}

// 存储p2p mes
func Save_p2pMes(mes *entity.P2PMsg) (err error) {
	//result := s_utils.DB.Create(mes)
	//if result.Error != nil {
	//	return result.Error
	//}
	//return nil
	var existing entity.P2PMsg
	err = s_utils.DB.Where("uuid = ?", mes.Uuid).First(&existing).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			// 不存在数据
			return s_utils.DB.Create(mes).Error
		}
		return err
	}
	return s_utils.DB.Model(&existing).Update(mes).Error
}

// 批量存储p2p_mes
func SaveP2PMessages(msgs []entity.P2PMsg) (retMsgs []entity.P2PMsg, err error) {
	if len(msgs) == 0 {
		return
	}
	// 因为用的是jinzhu的gorm，没有提供批量插入功能，用原生的又没返回ids
	// 现在要改回gorm.io版本的导致变动太大了，在这里先忽略不搞吧，展示功能就好==
	for _, msg := range msgs {
		_ = Save_p2pMes(&msg)
		retMsgs = append(retMsgs, msg)
	}

	// == 批量插入不会返回msg.id
	//// 构建SQL语句
	//var values []interface{}
	//var sqlBuilder strings.Builder
	//sqlBuilder.WriteString("INSERT INTO p2p_msgs (receive_id, send_id, type, content, is_read, send_time) VALUES ")
	//
	//// 拼接值
	//for i, msg := range msgs {
	//	if i > 0 {
	//		sqlBuilder.WriteString(", ")
	//	}
	//	sqlBuilder.WriteString("(?, ?, ?, ?, ?, ?)")
	//
	//	// 将每条记录的值添加到 values 列表中
	//	values = append(values, msg.ReceiveId, msg.SendId, msg.Type, msg.Content, msg.IsRead, msg.SendTime)
	//}
	//
	//// 执行原生 SQL 批量插入
	//sql := sqlBuilder.String()
	//err = s_utils.DB.Exec(sql, values...).Error
	//if err != nil {
	//	return err
	//}

	return
}

// 创建群聊
func CreateGroup(g *entity.Group) (err error) {
	tx := s_utils.DB.Begin()
	ret := s_utils.DB.Create(g)
	if ret.Error != nil {
		tx.Rollback()
		return ret.Error
	}
	var user entity.User
	res := s_utils.DB.Where("id=?", g.OwnerUser).Find(&user)
	if res.Error != nil {
		tx.Rollback()
		return res.Error
	}
	user.Group_id = append(user.Group_id, g.ID)
	res = s_utils.DB.Model(&user).Updates(map[string]interface{}{
		"group_id": user.Group_id,
	})
	if res.Error != nil {
		tx.Rollback()
		return res.Error
	}

	// 提交事务
	if err = tx.Commit().Error; err != nil {
		return err
	}
	return nil
}

// 为群聊添加成员 / 群聊成员同意加入 / 用户资料的group_id得多一段数据
func AddMember2Group(gid uint, memberId uint, isRefused uint) (err error) {
	tx := s_utils.DB.Begin()
	if tx.Error != nil {
		return tx.Error
	}
	g := &entity.Group{}
	ret := s_utils.DB.Where("id=?", gid).First(&g)
	if ret.Error != nil {
		tx.Rollback()
		return ret.Error
	}
	g.Members = append(g.Members, memberId)
	ret = s_utils.DB.Model(&g).Updates(map[string]interface{}{
		"members": g.Members,
	})
	if ret.Error != nil {
		return ret.Error
	}

	gi := &entity.GroupInvite{
		GroupId:      gid,
		MemberId:     memberId,
		IsRefused:    isRefused,
		IsMemberDeal: 1,
	}
	res := s_utils.DB.Model(&entity.GroupInvite{}).
		Where("group_id = ? AND member_id = ?", gid, memberId).
		Updates(map[string]interface{}{
			"is_refused":     gi.IsRefused,
			"is_member_deal": gi.IsMemberDeal,
		})
	if res.Error != nil {
		tx.Rollback()
		return res.Error
	}

	var user entity.User
	res = s_utils.DB.Where("id=?", memberId).Find(&user)
	if res.Error != nil {
		tx.Rollback()
		return res.Error
	}
	user.Group_id = append(user.Group_id, gid)
	res = s_utils.DB.Model(&user).Updates(map[string]interface{}{
		"group_id": user.Group_id,
	})
	if res.Error != nil {
		tx.Rollback()
		return res.Error
	}

	// 提交事务
	if err = tx.Commit().Error; err != nil {
		return err
	}
	return nil
}

// 群聊邀请通知 创建
func GroupInvite(gi *entity.GroupInvite) (err error) {
	res := s_utils.DB.Create(gi)
	if res.Error != nil {
		return res.Error
	}
	return nil
}

// 群聊邀请通知 用户登录时通知
func GroupInviteNotify(member_id uint) (gids []entity.GroupInvite, err error) {
	res := s_utils.DB.Where("member_id=?", member_id).Find(&gids)
	if res.Error != nil {
		return nil, res.Error
	}
	return gids, nil
}

// 用户查询邀请自己的群聊
func FindGIbyId(member_id uint) (gs []entity.Group, err error) {
	sql := `
        SELECT id, group_name, owner_user, members 
        FROM ` + "`group`" + ` 
        WHERE id IN (
            SELECT group_id 
            FROM group_invite 
            WHERE is_member_deal = ? AND is_refused = ? AND member_id = ?
        )
    `
	if err := s_utils.DB.Raw(sql, 0, 0, member_id).Scan(&gs).Error; err != nil {
		return nil, err
	}
	return gs, nil
}

// 保存群聊消息
func SaveGroupMes(gm *entity.GroupMsg) (err error) {
	ret := s_utils.DB.Create(gm)
	if ret.Error != nil {
		return ret.Error
	}
	return nil
}

// 发送群聊消息: 查找需要推送给哪些个用户
func FindUserGMes(sendId uint, gid uint) (members []uint, err error) {
	var group entity.Group
	if err := s_utils.DB.
		Select("members").
		Where("id = ?", gid).
		First(&group).Error; err != nil {
		return nil, err
	}
	rets := []uint{}
	for _, m := range group.Members {
		if m == sendId {
			continue
		}
		rets = append(rets, m)
	}
	return rets, nil
}

func NoteP2PRead(UUIDs []string) (err error) {
	if len(UUIDs) == 0 {
		return
	}
	err = s_utils.DB.Model(&entity.P2PMsg{}).
		Where("uuid IN (?)", UUIDs).
		Update("is_read", true).Error
	if err != nil {
		fmt.Println("更新失败:", err)
	}
	return nil
}

func NoteGmRead(uid uint, gm *entity.GroupMsg) (err error) {
	newReadMember := append(gm.ReadMember, uid)
	res := s_utils.DB.Model(gm).Updates(map[string]interface{}{
		"read_member": newReadMember,
	})
	if res.Error != nil {
		err = res.Error
		return err
	}
	return nil
}

// 查找聊天记录
func FindChattingRec(sid uint, tid uint) (p2pMsg2 []entity.P2PMsg, err error) {
	err = s_utils.DB.
		Where("(receive_id = ? AND send_id = ?) OR (receive_id = ? AND send_id = ?)", tid, sid, sid, tid).
		Order("send_time DESC").
		Limit(10).
		Find(&p2pMsg2).Error
	if err != nil {
		return nil, err
	}
	return p2pMsg2, nil
}
